package project.tool4nat.server.handler;

import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import project.tool4nat.common.ChannelManager;
import project.tool4nat.common.Constants;
import project.tool4nat.common.DataPack;

import static project.tool4nat.common.Constants.TYPE_CONNECT;
import static project.tool4nat.common.Constants.TYPE_TRANSFER;

public class ServerTunnelHandler extends SimpleChannelInboundHandler<DataPack> {

    private final static Logger logger = LoggerFactory.getLogger(ServerTunnelHandler.class);

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
//        logger.info("server tunnel active");
//        ChannelManager.setProxyTunnel(ctx.channel());
        super.channelActive(ctx);
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        logger.info("server tunnel inactive");
        ChannelManager.setProxyTunnel(null);
        super.channelInactive(ctx);
    }

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, DataPack msg) throws Exception {
//        logger.info("channel hashcode={}", ctx.channel().hashCode());
//        ChannelManager.add(ctx.channel());
//        logger.info("channel size={}", ChannelManager.getSize());
        long cid = msg.getCid();
        byte type = msg.getType();
        byte[] data = msg.getData();
//        logger.info("receive msg from proxy client for caller(cid={})\r\n{}", cid, new String(data));
        switch (type) {
            case TYPE_CONNECT:
                doConnect(ctx.channel());
                break;
            case TYPE_TRANSFER:
                doTransfer(msg);
                break;
        }

    }

    private void doTransfer(DataPack msg) {
        long cid = msg.getCid();
        byte[] data = msg.getData();
        Channel caller = ChannelManager.getCaller(cid);
        if (caller != null) {
            caller.writeAndFlush(Unpooled.wrappedBuffer(data));
        }
    }

    private void doConnect(Channel channel) {
        ChannelManager.setProxyTunnel(channel);
    }

}
